home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / timeline / movecnvs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  15.7 KB  |  385 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/collab/TimeLine/RCS/moveCanvas.c,v 1.0 91/09/30 16:58:54 chua Exp Locker: drapeau $ */
  25. /* $Log:    moveCanvas.c,v $
  26.  * Revision 1.0  91/09/30  16:58:54  chua
  27.  * Update to version 1.0
  28.  * 
  29.  * Revision 0.47  91/09/23  17:11:48  chua
  30.  * In ResetCanvas, clear any selected region.
  31.  * 
  32.  * Revision 0.46  91/09/20  13:05:30  chua
  33.  * In ResetCanvas, also move the playback head back to zero.
  34.  * 
  35.  * Revision 0.45  91/09/19  17:28:54  chua
  36.  * Make sure that variables are initialized properly.  Change formatting slightly,
  37.  * so that (if, for, while) statements with only one statement in them will not have
  38.  * braces.
  39.  * 
  40.  * Revision 0.44  91/08/05  16:53:14  chua
  41.  * Deleted the RepaintCanvas routine, as it is no longer necessary.  In places where it
  42.  * is called, just call the ScrollToFirstQuarter routine, which will do the necessary
  43.  * repaint as well.
  44.  * 
  45.  * Revision 0.43  91/08/05  13:03:03  chua
  46.  * Added the routines to scroll fast the canvas both left and right, and also to reset the canvas
  47.  * back to the starting position.
  48.  * 
  49.  * In the ScrollToMiddle function, change the name to ScrollToFirstQuarter.  Now, we position
  50.  * the parameter, quarter, to the first quarter of the canvas, instead of in the middle, as
  51.  * previously.
  52.  * 
  53.  * Revision 0.42  91/07/22  15:18:38  chua
  54.  * Added a new procedure, ScrollToMiddle, which will scroll or remap the canvas, such that the
  55.  * position given by the parameter, middle, will be in the center of the canvas.
  56.  * 
  57.  * Revision 0.41  91/07/17  10:27:12  chua
  58.  * *** empty log message ***
  59.  * 
  60.  * Revision 0.40  91/07/17  10:24:44  chua
  61.  * This file contains the functions dealing with the scrolling of the canvas, or
  62.  * remapping the canvas to another part of the TimeLine.
  63.  * It also contains the notify procedures for the move canvas left and move canvas
  64.  * right buttons.
  65.  * 
  66.  * The functions dealing with the scrolling/remapping of the draw canvas are:
  67.  * 
  68.  * ShowNewCanvas
  69.  * VerticalScrollHandler
  70.  * HorizontalScrollHandler
  71.  * CheckHorizontalScrolling
  72.  * CheckVerticalScrolling
  73.  *  */
  74.  
  75. static char moveCanvasrcsid[] = "$Header: /Source/Media/collab/TimeLine/RCS/moveCanvas.c,v 1.0 91/09/30 16:58:54 chua Exp Locker: drapeau $";
  76. #include "main.h"
  77.  
  78. /*
  79.  * Notify callback function for `MoveCanvasLeftButton'.
  80.  * Move the canvas left by one screen.
  81.  */
  82. void MoveCanvasLeft(item, event)
  83.      Panel_item    item;
  84.      Event        *event;
  85. {
  86.   int viewLength;
  87.   TimeLineFramePtr tlFrame;
  88.   TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  89.   
  90.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  91.   viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  92.   if (tlFrame->canvasStart != 0) 
  93.   {
  94.     tlFrame->canvasStart -= viewLength;
  95.     tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond) 
  96.       + (TimeLineInterval * PixelsPerSecond);
  97.     if (tlFrame->canvasStart < 0) 
  98.       tlFrame->canvasStart = 0;
  99.     ShowNewCanvas(tlFrame, 1);
  100.   }
  101. }
  102.  
  103. /*
  104.  * Notify callback function for `MoveCanvasRightButton'.
  105.  * Move the canvas right by one screen.
  106.  */
  107. void MoveCanvasRight(item, event)
  108.      Panel_item    item;
  109.      Event        *event;
  110. {
  111.   int viewLength;
  112.   TimeLineFramePtr tlFrame;
  113.   TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  114.   
  115.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  116.   viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  117.   tlFrame->canvasStart += viewLength;
  118.   tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond);
  119.   ShowNewCanvas(tlFrame, 1);
  120. }
  121.  
  122. /*
  123.  * Notify callback function for `MoveCanvasFastLeftButton'.
  124.  * Move the canvas left by three screen.
  125.  */
  126. void MoveCanvasFastLeft(item, event)
  127.      Panel_item    item;
  128.      Event        *event;
  129. {
  130.   int viewLength;
  131.   TimeLineFramePtr tlFrame;
  132.   TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  133.   
  134.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  135.   viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  136.   if (tlFrame->canvasStart != 0) 
  137.   {
  138.     tlFrame->canvasStart -= viewLength * 3;
  139.     tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond) 
  140.       + (TimeLineInterval * PixelsPerSecond);
  141.     if (tlFrame->canvasStart < 0) 
  142.       tlFrame->canvasStart = 0;
  143.     ShowNewCanvas(tlFrame, 1);
  144.   }
  145. }
  146.  
  147. /*
  148.  * Notify callback function for `MoveCanvasFastRightButton'.
  149.  * Move the canvas right by three screen.
  150.  */
  151. void MoveCanvasFastRight(item, event)
  152.      Panel_item    item;
  153.      Event        *event;
  154. {
  155.   int viewLength;
  156.   TimeLineFramePtr tlFrame;
  157.   TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  158.   
  159.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  160.   viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  161.   tlFrame->canvasStart += viewLength * 3;
  162.   tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond);
  163.   ShowNewCanvas(tlFrame, 1);
  164. }
  165.  
  166. /*
  167.  * Notify callback function for `ResetCanvasButton'.
  168.  * Reset the canvas to start at time 0.  Also reset the playback head position.
  169.  */
  170. void ResetCanvas(item, event)
  171.      Panel_item    item;
  172.      Event        *event;
  173. {
  174.   TimeLineFramePtr tlFrame;
  175.   TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  176.   
  177.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  178.   if (tlFrame->areaSelected == 1)                    /* Deselect any selected region */
  179.   {
  180.     XDrawRectangle(tlFrame->dpyDraw, tlFrame->xidDraw, tlFrame->gcLine, (tlFrame->startX  / tlFrame->zoomLevel) - tlFrame->canvasStart, 
  181.            tlFrame->startY, (tlFrame->endX - tlFrame->startX) / tlFrame->zoomLevel,
  182.            tlFrame->endY - tlFrame->startY);
  183.     tlFrame->startX = tlFrame->endX = tlFrame->startY = tlFrame->endY = 0;
  184.     DrawSelectArea(tlFrame);
  185.   }
  186.   DeselectNote(tlFrame);                        /* Deselect any selected note */
  187.   DrawPlaybackHead(-1, tlFrame);
  188.   tlFrame->canvasStart = 0;
  189.   ShowNewCanvas(tlFrame, 1);
  190. }
  191.  
  192. /*
  193.  * This function is called when we are changing the segment of timeline that is being displayed on the current canvas (moving canvas right or left, or
  194.  * during playback scrolling).  
  195.  * It will check if any area has been selected and if it should be drawn on the new display.  It will then refresh both the draw and time canvases to
  196.  * show the new segment of the timeline.
  197.  */
  198. void ShowNewCanvas(tlFrame, canvasStart)
  199.      TimeLineFramePtr tlFrame;
  200.      int canvasStart;
  201. {
  202.   int viewLength;
  203.   
  204.   viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  205.   if (canvasStart > tlFrame->TimeLineLength - viewLength) 
  206.     canvasStart = tlFrame->TimeLineLength - viewLength - 1;
  207.   xv_set(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START, 
  208.      canvasStart, NULL);
  209.   DrawCanvasRepaintHandler(tlFrame->TimeLine_window->DrawCanvas, tlFrame->paintWinDraw, 
  210.                tlFrame->dpyDraw, tlFrame->xidDraw, NULL);
  211.   TimeCanvasRepaintHandler(tlFrame->TimeLine_window->AppCanvas, tlFrame->paintWinApp, 
  212.                tlFrame->dpyApp, tlFrame->xidApp, NULL);
  213. }
  214.  
  215. /*
  216.  * Notify interpose function to vertically scroll both the App canvas and Draw canvas simultaneously. 
  217.  * This is required so as to accomodate more open applications than can be displayed on the screen at the same time.
  218.  * This function is called when the vertical scrollbar of the App canvas is pressed/moved.
  219.  */
  220. Notify_value  VerticalScrollHandler (win, event, arg, type)
  221.      Xv_window         win;
  222.      Event             *event;
  223.      Notify_arg         arg;
  224.      Notify_event_type     type;
  225. {
  226.   int viewStart;                            /* The current canvas position at the left edge of the viewing window */
  227.   TimeLineFramePtr tlFrame;
  228.   TimeLine_window_objects    *ip;
  229.   Canvas canvas = xv_get(win, XV_OWNER);
  230.  
  231.   ip = (TimeLine_window_objects *) xv_get(canvas, XV_KEY_DATA, INSTANCE);
  232.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  233.   switch (event_action(event)) 
  234.   {
  235.    case SCROLLBAR_REQUEST:
  236.     viewStart = (int) xv_get (arg, SCROLLBAR_VIEW_START);
  237.     xv_set (tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_START, 
  238.         viewStart, NULL);                        /* Set the canvas position of the Draw canvas to the same as for the App canvas */
  239.     break;
  240.    default:
  241.     break;
  242.   }
  243.   return notify_next_event_func(win, (Notify_event)event, arg, type);
  244. }
  245.  
  246. /*
  247.  * Notify interpose function to horizontally scroll both the Draw canvas and Time canvas simultaneously. 
  248.  * This is required so that the timeline will move along with the notes during playback or scrolling done by the user.
  249.  * This function is called when the horizontal scrollbar of the Draw canvas is pressed/moved.
  250.  */
  251. Notify_value  HorizontalScrollHandler (win, event, arg, type)
  252.      Xv_window         win;
  253.      Event             *event;
  254.      Notify_arg         arg;
  255.      Notify_event_type     type;
  256. {
  257.   int viewStart;                            /* The current canvas position at the top edge of the viewing window */
  258.   int viewLength;
  259.   int previousStart;
  260.   TimeLineFramePtr tlFrame;
  261.   TimeLine_window_objects    *ip;
  262.   Canvas canvas = xv_get(win, XV_OWNER);
  263.  
  264.   ip = (TimeLine_window_objects *) xv_get(canvas, XV_KEY_DATA, INSTANCE);
  265.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  266.   switch (event_action(event)) 
  267.   {
  268.    case SCROLLBAR_REQUEST:
  269.     if (arg == tlFrame->DrawScrollbarHor)                /* For some reason, this function gets called when the App canvas vertical scrollbar */
  270.     {                                    /* is pressed as well.  Thus the need for the if statement so that the scrolling */
  271.                                     /* is executed only if this function is called by the Draw canvas horizontal */
  272.                                     /* scrollbar */
  273.  
  274.       viewStart = (int) xv_get (arg, SCROLLBAR_VIEW_START);
  275.       viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  276.       if (viewStart >= tlFrame->TimeLineLength - viewLength)        /* Check if switching to a new canvas view is necessary */
  277.       {
  278.     tlFrame->canvasStart = tlFrame->canvasStart + tlFrame->TimeLineLength - viewLength;
  279.     tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond);
  280.     ShowNewCanvas(tlFrame, 1);
  281.       }
  282.       else if (viewStart <= 0 && tlFrame->canvasStart != 0)
  283.       {
  284.     previousStart = tlFrame->canvasStart;
  285.     tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->TimeLineLength + viewLength;
  286.     tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond) 
  287.       + (TimeLineInterval * PixelsPerSecond);
  288.     if (tlFrame->canvasStart < 0) 
  289.       tlFrame->canvasStart = 0;
  290.     viewStart = previousStart - tlFrame->canvasStart - 1;
  291.     ShowNewCanvas (tlFrame, viewStart);
  292.       }
  293.       else 
  294.     xv_set (tlFrame->TimeScrollbar, SCROLLBAR_VIEW_START, viewStart, NULL);
  295.       scrollHorStart = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START); /* Get the canvas window horizontal and vertical start and end points */
  296.       scrollHorEnd = scrollHorStart + xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  297.     }
  298.     break;
  299.    default:
  300.     break;
  301.   }
  302.   return notify_next_event_func(win, (Notify_event)event, arg, type);
  303. }
  304.  
  305. /*
  306.  * Function to check if horizontal scrolling is required.  Scrolling is required when the user drags the mouse off the canvas window and it is not
  307.  * at the end of the canvas.  The canvas scrolls by 10 pixels each time.
  308.  * Called by DrawCanvasRepaintHandler (canvas.c)
  309.  */
  310. void CheckHorizontalScrolling (xPos, tlFrame)
  311.      int xPos;
  312.      TimeLineFramePtr tlFrame;
  313. {
  314.   if (xPos <= scrollHorStart)                        /* Check if scrolling left is required */
  315.   {
  316.     if ((scrollHorStart = scrollHorStart - 10) < 0) 
  317.       scrollHorStart = 0;
  318.     xv_set(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START, scrollHorStart, NULL);
  319.     scrollHorEnd = scrollHorStart + xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  320.   }
  321.   else if (xPos >= scrollHorEnd)                    /* Check if scrolling right is required */
  322.   {
  323.     if ((scrollHorStart = scrollHorStart + 10) > 
  324.     tlFrame->TimeLineLength - xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH)) 
  325.       scrollHorStart = tlFrame->TimeLineLength - xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH); 
  326.     xv_set(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START, scrollHorStart, NULL);
  327.     scrollHorEnd = scrollHorStart + xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  328.   }
  329. }
  330.  
  331. /*
  332.  * Function to check if vertical scrolling is required.  Scrolling is required when the user drags the mouse off the canvas window and it is not
  333.  * at the end of the canvas.  The canvas scrolls by the height of one track each time.
  334.  * Called by DrawCanvasRepaintHandler (canvas.c)
  335.  */
  336. void CheckVerticalScrolling (yPos, tlFrame)
  337.      int yPos;
  338.      TimeLineFramePtr tlFrame;
  339. {
  340.   if (yPos <= scrollVerStart)                        /* Check if scrolling left is required */
  341.   {
  342.     if ((scrollVerStart = scrollVerStart - (IconHeight + IconGap)) < 0) 
  343.       scrollVerStart = 0;
  344.     xv_set(tlFrame->AppScrollbar, SCROLLBAR_VIEW_START, scrollVerStart, NULL);
  345.     scrollVerEnd = scrollVerStart + xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH);
  346.   }
  347.   else if (yPos >= scrollVerEnd)                    /* Check if scrolling right is required */
  348.   {
  349.     if ((scrollVerStart = scrollVerStart + (IconHeight + IconGap)) > ((tlFrame->numberOfApps + 1) * (IconHeight + IconGap)
  350.                         - xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH))) 
  351.       scrollVerStart = (tlFrame->numberOfApps+1) * (IconHeight + IconGap)
  352.     - xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH); 
  353.     xv_set(tlFrame->AppScrollbar, SCROLLBAR_VIEW_START, scrollVerStart, NULL);
  354.     scrollVerEnd = scrollVerStart + xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH);
  355.   }
  356. }
  357.  
  358. /*
  359.  * This function will scroll or remap the canvas such that the value passed in by the parameter quarter, is in the first quarter of the canvas.
  360.  * The parameter refresh indicates if we definitely want to redraw the canvas, regardless of where the quarter is already in the window.
  361.  */
  362. void ScrollToFirstQuarter(tlFrame, quarter, refresh) 
  363.      TimeLineFramePtr tlFrame;
  364.      int quarter;
  365.      int refresh;
  366. {
  367.   int scrollStart, scrollEnd;
  368.   int viewLength;
  369.  
  370.   viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
  371.   scrollStart = (xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START) + tlFrame->canvasStart) *
  372.     tlFrame->zoomLevel;                            /* Check if it is necessary to scroll the canvas.  Scrolling is done only */
  373.   scrollEnd = scrollStart + (viewLength * tlFrame->zoomLevel);        /* if the start of the note is not visible */
  374.   if (quarter < scrollStart || quarter > scrollEnd) 
  375.   {
  376.     tlFrame->canvasStart = (quarter / tlFrame->zoomLevel) - (viewLength / 4);
  377.     if (tlFrame->canvasStart < 0) 
  378.       tlFrame->canvasStart = 0;
  379.     tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond); 
  380.     ShowNewCanvas(tlFrame, 1);
  381.   }
  382.   else if (refresh == 1) 
  383.     ShowNewCanvas(tlFrame, 1);
  384. }
  385.